using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Content.Pipeline;
using Microsoft.Xna.Framework.Content.Pipeline.Graphics;
using Microsoft.Xna.Framework.Content.Pipeline.Processors;
using Microsoft.Xna.Framework.Content.Pipeline.Serialization.Compiler;
using Utility2DLibrary;
// TODO: replace this with the type you want to write out.
using TWrite = Utility2DLibrary.ShipPartPrimitive;

namespace UtilityContentPipelineExtension
{
    /// <summary>
    /// This class will be instantiated by the XNA Framework Content Pipeline
    /// to write the specified data type into binary .xnb format.
    ///
    /// This should be part of a Content Pipeline Extension Library project.
    /// </summary>
    [ContentTypeWriter]
    public class ShipPartPrimitiveTypeReaderWriter : ContentTypeWriter<TWrite>
    {
        protected override void Write(ContentWriter output, TWrite value)
        {
            output.Write(value.Scale);
            output.Write(value.Mass);
            //output.WriteObject<List<Vector2>>(value.VertexList);
            output.Write(value.VertexFile);
            output.Write(value.TextureFile);
            output.Write(value.ShaderEffectFile);
            output.Write(value.PositionVector);
            output.Write(value.Orientation);
        }

        public override string GetRuntimeReader(TargetPlatform targetPlatform)
        {
            return typeof(ShipPartPrimitiveContentReader).AssemblyQualifiedName;
        }
    }
    public class ShipPartPrimitiveContentReader : ContentTypeReader<TWrite>
    {
        protected override TWrite Read(ContentReader input, TWrite existingInstance)
        {
            Vector2 theScale = input.ReadVector2();
            float theTotalMass = input.ReadSingle();
            //List<Vector2> thePoints = input.ReadObject<List<Vector2>>();
            List<Vector2> thePoints = input.ReadExternalReference<List<Vector2>>();
            Texture2D theTexture = input.ReadExternalReference<Texture2D>();
            Effect theShader = input.ReadExternalReference<Effect>();
            Vector2 thePosition = input.ReadVector2();
            float theAngle = MathHelper.ToRadians(input.ReadSingle());
            
            Utility2DLibrary.ShipPartPrimitive part = existingInstance;
            if (part == null)
            {
                part = new ShipPartPrimitive(theShader, theTexture, new Utility2DLibrary.Point(thePosition), theAngle);
            }
            else
            {
                part.ShaderEffect = theShader;
                part.PolyTexture = theTexture;
                part.PositionVector = thePosition;
                part.Orientation = theAngle;
            }
            part.Scale = theScale;
            float averageMass = theTotalMass / 3;
            foreach (Vector2 vectorPoint in thePoints)
            {
                Utility2DLibrary.Point point = new Utility2DLibrary.Point(vectorPoint);
                part.PrimitivePoints.Add(new MassPoint(point, averageMass));
            }
            part.CalculateCenterOfMass();
            return part;
        }
    }
}
